package com.xinyue.auto.reader.major;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Element;
import org.dom4j.Node;

import com.xinyue.auto.annotation.ListClear;
import com.xinyue.auto.bean.Attribute;
import com.xinyue.auto.bean.Query;
import com.xinyue.auto.reader.Process;
import com.xinyue.auto.reader.ProcessContext;
import com.xinyue.auto.reader.util.JavaTypeUtil;
import com.xinyue.auto.util.StringUtil;

public abstract class RelyMajor extends ProcessContext{
	public RelyMajor(Process read) {
		super(read);
	}
	
	//属性集合
	@ListClear
	protected List<Attribute> atts = new ArrayList<Attribute>();
	//查询方法集合
	@ListClear
	protected List<Query> querys = new ArrayList<Query>();
	
	//标签数据封装对象
	protected Attribute att;
	//查询方法封装对象
	protected Query query;
	
	//实体名称
	protected String entity;
	//映射属性名称
	protected String key;
	//查询入参属性
	protected String queryType;

	/**
	 * 读取Id或者property的共有属性
	 * @param prop
	 * @return
	 * @throws Exception
	 */
	protected void commonRead(Element rely) throws Exception {
		//重置数据
		reset();
		
		String name = rely.attributeValue(name_);//属性名称
		//dao查询使用的数据
		entity = rely.attributeValue(entity_);//对应的实体对象
		key = rely.attributeValue(mapping_key_);//映射属性
		
		if(StringUtil.isNull(name)) {
			throw new Exception("没有定义name属性或其值为空");
		}
		if(StringUtil.isNull(entity)) {
			throw new Exception("没有定义entity属性或其值为空");
		}
		if(StringUtil.isNull(key)) {
			throw new Exception("没有定义mapping-key属性或其值为空");
		}
		
		//如果entity非本包Entity对象时
		if(entity.indexOf(".") > 0) {
			queryType = rely.attributeValue(type_);//映射属性类型
			if(StringUtil.isNull(queryType)) {
				throw new Exception("Entity实体不在本XML文件中时，必须定义type属性");
			}
			
			holder.getBeanImpt().add(entity);
			holder.getDaoImpt().add(entity);
			entity = StringUtil.getNameByDoc(entity);
		}else {
			//验证entity是否合法
			Node n = rely.selectSingleNode("/build-mapping/entity[@name='" + entity + "']");
			if(n == null) {
				throw new Exception("entity属性值非法：" + entity);
			}
			
			//验证mapping-key是否合法
			Node ex = n.selectSingleNode("id[@name='" + key + "']");
			if(ex == null) {
				ex = n.selectSingleNode("property[@name='" + key + "']");
			}
			
			//判断该属性是否存在
			if(ex == null) {
				throw new Exception("mapping-key属性值非法:" + key);
			}else {
				queryType = ex.valueOf("@type");
			}
			
			holder.getBeanImpt().add(holder.getBasePkg() + ".bean." + entity);
			holder.getDaoImpt().add(holder.getBasePkg() + ".bean." + entity);
		}
		
		//验证属性类型 注：mapping-key可以是Java基本类型，也可以是引用类型
		String impt = JavaTypeUtil.validate(queryType);
		if(impt != null) {
			holder.getDaoImpt().add(impt);
		}
		
		//属性名称和描述信息
		att.setName(name);
		att.setDesc(rely.attributeValue(desc_));
		
		//添加注解
		String[] temp = {"@Transient"};
		att.setAnnotations(temp);
		holder.getBeanImpt().add("javax.persistence.Transient");
	}
	
	@Override
	protected void install() {
		//将此属性添加至Entity对象中
		holder.getEntity().getAtts().addAll(atts);
		holder.getEntity().getFinds().addAll(querys);
	}
	
	/**
	 * 重置数据
	 */
	private void reset() {
		att = new Attribute();
		query = new Query();
	}

	//处理数据库查询语句
	protected abstract void process();
}